{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "hMMdZ1vnxj8f"
   },
   "source": [
    "<center>\n",
    "    <p style=\"text-align:center\">\n",
    "        <img alt=\"phoenix logo\" src=\"https://storage.googleapis.com/arize-phoenix-assets/assets/phoenix-logo-light.svg\" width=\"200\"/>\n",
    "        <br>\n",
    "        <a href=\"https://arize.com/docs/phoenix/\">Docs</a>\n",
    "        |\n",
    "        <a href=\"https://github.com/Arize-ai/phoenix\">GitHub</a>\n",
    "        |\n",
    "        <a href=\"https://arize-ai.slack.com/join/shared_invite/zt-2w57bhem8-hq24MB6u7yE_ZF_ilOYSBw#/shared-invite/email\">Community</a>\n",
    "    </p>\n",
    "</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "se3M7GECJfpZ"
   },
   "source": [
    "# AutoGen Prompt Chaining Agent\n",
    "\n",
    "In this tutorial, we'll explore **prompt chaining** with [AutoGen agents](https://microsoft.github.io/autogen/0.2/docs/Getting-Started) and how to trace using Phoenix.\n",
    "Prompt chaining is a method where a complex task is broken into smaller, linked subtasks, with the output of one step feeding into the next. This workflow is ideal when a task can be cleanly decomposed into fixed subtasks, making each LLM call simpler and more accurate — trading off latency for better overall performance.\n",
    "\n",
    "AutoGen makes it easy to build these chains by coordinating multiple agents. Each `AssistantAgent` focuses on a specialized task, while a `UserProxyAgent` manages the conversation flow and passes key outputs between steps. With Phoenix tracing, we can visualize the entire sequence, monitor individual agent calls, and debug the chain more easily.\n",
    "\n",
    "In this example, we'll create a multi-step market analysis workflow, from identifying trends to evaluating company strengths — all automated and fully traceable.\n",
    "\n",
    "By the end of this tutorial, you’ll learn how to:\n",
    "\n",
    "- Set up specialized AutoGen agents\n",
    "\n",
    "- Chain tasks across agents with carryover context\n",
    "\n",
    "- Improve task accuracy by simplifying each LLM call\n",
    "\n",
    "- Trace and visualize the full execution using Phoenix\n",
    "\n",
    "⚠️ You'll need an OpenAI Key for this tutorial."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "G2j6_RvFJfpa"
   },
   "source": [
    "## Set up Keys and Dependencies\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install -qq pyautogen==0.9 autogen-agentchat~=0.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install -qqq arize-phoenix arize-phoenix-otel openinference-instrumentation-openai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from getpass import getpass\n",
    "\n",
    "import autogen\n",
    "\n",
    "if \"OPENAI_API_KEY\" not in os.environ:\n",
    "    os.environ[\"OPENAI_API_KEY\"] = getpass(\"🔑 Enter your OpenAI API key: \")\n",
    "\n",
    "if \"PHOENIX_API_KEY\" not in os.environ:\n",
    "    os.environ[\"PHOENIX_API_KEY\"] = getpass(\"🔑 Enter your Phoenix API key: \")\n",
    "\n",
    "if \"PHOENIX_COLLECTOR_ENDPOINT\" not in os.environ:\n",
    "    os.environ[\"PHOENIX_COLLECTOR_ENDPOINT\"] = getpass(\"🔑 Enter your Phoenix Collector Endpoint\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ibmucjY_QkaH"
   },
   "source": [
    "## Configure Tracing\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from phoenix.otel import register\n",
    "\n",
    "tracer_provider = register(\n",
    "    project_name=\"autogen-agents\",\n",
    "    auto_instrument=True,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "kTVRWf0NJfpc"
   },
   "source": [
    "## Example Prompt Chaining Task: Market Analyzer\n",
    "\n",
    "This example demonstrates how to use AutoGen agents to solve a chained series of market analysis tasks, while capturing detailed tracing with Phoenix. A main user agent delegates each task to a specialized expert agent.\n",
    "\n",
    "Each task builds on the results of the previous one: after an agent completes its task, a summary of its output is passed as carryover context into the next agent's conversation. This ensures that every agent has access to relevant information gathered so far, allowing later steps to benefit from earlier research."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "qq5TvGKzO685"
   },
   "source": [
    "## Define Agent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "dpjxM6BGLGW0"
   },
   "source": [
    "First, we define four specialized `AssistantAgents`, each responsible for a different part of a market analysis workflow: analyzing market trends, identifying top-performing companies, comparing companies, and evaluating strengths and weaknesses. We also define a `UserProxyAgent` that acts as the coordinator, automatically sending tasks to the assistants and managing the overall conversation flow. The `human_input_mode` is set to \"NEVER\", meaning the user agent operates autonomously without waiting for manual input.\n",
    "\n",
    "The `llm_config` specifies the configuration used for all the assistant agents.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ntFdtQNHP_22"
   },
   "source": [
    "![Agent Set up](https://storage.googleapis.com/arize-phoenix-assets/assets/images/autogen_prompt_chaining.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "market_analysis_tasks = [\n",
    "    \"\"\"What is the latest market trend in the technology sector? Focus on freely accessible sources like news websites, research blogs, and online publications.\"\"\",\n",
    "    \"\"\"Based on the identified market trend, what are the top 5 companies currently leading in that sector? Focus on freely accessible sources like news websites, research blogs, and online publications.\"\"\",\n",
    "    \"\"\"Perform a comparison between these top 5 companies in terms of stock performance, revenue growth, and product innovation over the past year. Focus on freely accessible sources like news websites, research blogs, and online publications.\"\"\",\n",
    "    \"\"\"Summarize the strengths and weaknesses of these companies in terms of their market positioning and potential for future growth.\"\"\",\n",
    "]\n",
    "\n",
    "config_list = [\n",
    "    {\n",
    "        \"model\": \"gpt-4o\",\n",
    "        \"api_key\": os.environ[\"OPENAI_API_KEY\"],\n",
    "    }\n",
    "]\n",
    "\n",
    "llm_config = {\"config_list\": config_list}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "market_trend_assistant = autogen.AssistantAgent(\n",
    "    name=\"MarketTrendAssistant\",\n",
    "    llm_config=llm_config,\n",
    ")\n",
    "\n",
    "top_companies_assistant = autogen.AssistantAgent(\n",
    "    name=\"TopCompaniesAssistant\",\n",
    "    llm_config=llm_config,\n",
    ")\n",
    "\n",
    "company_comparison_assistant = autogen.AssistantAgent(\n",
    "    name=\"CompanyComparisonAssistant\",\n",
    "    llm_config=llm_config,\n",
    ")\n",
    "\n",
    "strength_weakness_assistant = autogen.AssistantAgent(\n",
    "    name=\"StrengthWeaknessAssistant\",\n",
    "    llm_config=llm_config,\n",
    ")\n",
    "\n",
    "# User agent\n",
    "user = autogen.UserProxyAgent(\n",
    "    name=\"User\",\n",
    "    human_input_mode=\"NEVER\",\n",
    "    is_termination_msg=lambda x: x.get(\"content\", \"\")\n",
    "    and x.get(\"content\", \"\").rstrip().endswith(\"TERMINATE\"),\n",
    "    code_execution_config={\n",
    "        \"last_n_messages\": 1,\n",
    "        \"work_dir\": \"tasks\",\n",
    "        \"use_docker\": False,\n",
    "    },\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "wXIhcyi6PGKk"
   },
   "source": [
    "## Run Agent\n",
    "Finally, we use `user.initiate_chats` to send each task to the appropriate specialized agent. Each agent receives its specific task, processes it, and produces a summary that can be carried over to the next step. The first task clears any prior conversation history, while the following tasks use reflection with an LLM to summarize and pass forward important context.\n",
    "\n",
    "The AutoGen agent not only handles the task flow but also generates and executes code for desired outcomes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from opentelemetry.trace import StatusCode\n",
    "\n",
    "tracer = tracer_provider.get_tracer(__name__)\n",
    "\n",
    "# Initiating the chats\n",
    "with tracer.start_as_current_span(\n",
    "    \"MarketAnalysisAgent\",\n",
    "    openinference_span_kind=\"agent\",\n",
    ") as agent_span:\n",
    "    agent_span.set_status(StatusCode.OK)\n",
    "    chat_results = user.initiate_chats(\n",
    "        [\n",
    "            {\n",
    "                \"recipient\": market_trend_assistant,\n",
    "                \"message\": market_analysis_tasks[0],\n",
    "                \"clear_history\": True,\n",
    "                \"silent\": False,\n",
    "                \"summary_method\": \"last_msg\",\n",
    "            },\n",
    "            {\n",
    "                \"recipient\": top_companies_assistant,\n",
    "                \"message\": market_analysis_tasks[1],\n",
    "                \"summary_method\": \"reflection_with_llm\",\n",
    "            },\n",
    "            {\n",
    "                \"recipient\": company_comparison_assistant,\n",
    "                \"message\": market_analysis_tasks[2],\n",
    "                \"summary_method\": \"reflection_with_llm\",\n",
    "            },\n",
    "            {\n",
    "                \"recipient\": strength_weakness_assistant,\n",
    "                \"message\": market_analysis_tasks[3],\n",
    "                \"summary_method\": \"reflection_with_llm\",\n",
    "            },\n",
    "        ]\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3uDT0wMMJfpd"
   },
   "source": [
    "# View Results in Phoenix"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "t36H8r1AZrxS"
   },
   "source": [
    "In Phoenix, you can track how each LLM call in a prompt chain builds on previous outputs, with context from earlier steps guiding subsequent responses.\n",
    "\n",
    "The tracing also shows the generated code AutoGen uses to fetch and process information, offering visibility into how the system interacts with external sources to complete tasks. This provides a clear view of the flow, from reasoning to code execution, ensuring accurate results.\n",
    "\n",
    "You can also see metadata like latency and token usage. This will help you spot optimization opportunities to improve your agent’s efficiency.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "kMZ5VqD_bWvq"
   },
   "source": [
    "![Results GIF](https://storage.googleapis.com/arize-phoenix-assets/assets/images/autogen_prompt_chaining.gif)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "eb-fRBTQahfU"
   },
   "source": [
    "Run the cell below to see full tracing results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import HTML\n",
    "\n",
    "HTML(\"\"\"\n",
    "<video width=\"800\" height=\"600\" controls>\n",
    "  <source src=\"https://storage.googleapis.com/arize-phoenix-assets/assets/images/autogen_prompt_chaining.mp4\" type=\"video/mp4\">\n",
    "  Your browser does not support the video tag.\n",
    "</video>\n",
    "\"\"\")"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
